package com.ubxtech.core.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.ubxtech.web.annotation.EncryptEnum;
import com.ubxtech.web.annotation.ResponseEncrypt;

import java.util.Collection;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Victor.Xiao
 * @since 2024-01-11 11:19
 **/
public class AttrReplaceUtil {

    /**
     * 通用的替换
     * 例如
     * List<User>的user只有roleId值,
     * List<Role>的Role有roleId和name值
     * 这个方法逻辑就是根据user的roleId值,从Role中根据roleId找到对应的name并设置到user中
     * AttrReplaceUtil.replaceName(
     *                 userList,
     *                 roleList,
     *                 User::getRoleId,
     *                 User::setName,
     *                 Role::getRoleId,
     *                 Role::getName);
     * @author Victor.Xiao
     * @since 2024-01-11 11:26
     * @param targetList 要替换的目标列表
     * @param sourceList 数据来源列表
     * @param targetGetIdFunc 目标数据的关键字段
     * @param targetSetConsumer 目标设置方法
     * @param sourceGetIdFunc 来源数据的关键字段
     * @param sourceGetNameFunc 来源数据的替换字段
    */
    public static <T,S,K> void replaceName(Collection<T> targetList,
                                               Collection<S> sourceList ,
                                               Function<? super T, K> targetGetIdFunc,
                                               BiConsumer<? super T,K> targetSetConsumer,
                                               Function<? super S, K> sourceGetIdFunc,
                                               Function<? super S, K> sourceGetNameFunc) {
        if (CollectionUtil.isEmpty(targetList)
                || CollectionUtil.isEmpty(sourceList)
                || targetGetIdFunc == null
                || targetSetConsumer == null
                || sourceGetIdFunc == null
                || sourceGetNameFunc == null
        ) {
            return;
        }
        Map<K,S> repalceDataMap = sourceList.stream().collect(Collectors.toMap(sourceGetIdFunc, e -> e, (k1, k2) -> k1));

        targetList.forEach(a -> {

            K key = targetGetIdFunc.apply(a);
            S value = repalceDataMap.get(key);
            if (value != null) {
                targetSetConsumer.accept(a, sourceGetNameFunc.apply(value));
            }
        });
    }

    public static String serialize(String str, ResponseEncrypt responseEncrypt)  {

        EncryptEnum type = responseEncrypt.type();
        switch (type) {
            // 自定义类型脱敏
            case CUSTOM_RULE:
                int startInclude= responseEncrypt.startInclude();
                int endExclude =responseEncrypt.endExclude();
                str = CharSequenceUtil.hide(str, startInclude, endExclude);
                break;
            // userId脱敏
            case USER_ID:
                str = String.valueOf(DesensitizedUtil.userId());
                break;
            // 中文姓名脱敏
            case CHINESE_NAME:
                str = DesensitizedUtil.chineseName(String.valueOf(str));
                break;
            // 身份证脱敏
            case ID_CARD:
                str = DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2);
                break;
            // 固定电话脱敏
            case FIXED_PHONE:
                str = DesensitizedUtil.fixedPhone(String.valueOf(str));
                break;
            // 手机号脱敏
            case MOBILE_PHONE:
                str = DesensitizedUtil.mobilePhone(String.valueOf(str));
                break;
            // 地址脱敏
            case ADDRESS:
                str = DesensitizedUtil.address(String.valueOf(str), 8);
                break;
            // 邮箱脱敏
            case EMAIL:
                str = DesensitizedUtil.email(String.valueOf(str));
                break;
            // 密码脱敏
            case PASSWORD:
                str = DesensitizedUtil.password(String.valueOf(str));
                break;
            // 中国车牌脱敏
            case CAR_LICENSE:
                str = DesensitizedUtil.carLicense(String.valueOf(str));
                break;
            // 银行卡脱敏
            case BANK_CARD:
                str = DesensitizedUtil.bankCard(String.valueOf(str));
                break;
            default:
        }
        return str;
    }
}
